package cz.uhk.max.beans;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.faces.event.ActionEvent;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jxl.JXLException;


import org.richfaces.model.TreeNode;
import org.richfaces.model.TreeNodeImpl;

import com.sun.facelets.FaceletContext;

import cz.uhk.max.model.IXLSFileData;
import cz.uhk.max.beans.base.BaseBean;
import cz.uhk.max.exceptions.EquationException;
import cz.uhk.max.matrix.impl.EquationImpl;
import cz.uhk.max.matrix.impl.EquationResult;
import cz.uhk.max.matrix.IEquation;
import cz.uhk.max.matrix.IEquationResult;
import cz.uhk.max.matrix.Matrix;
import cz.uhk.max.matrix.impl.MatrixDao;
import cz.uhk.max.util.DateUtils;

public class BackingBean extends BaseBean {
	private Matrix matrixA = new Matrix(new Integer(4), new Integer(3));
	private Matrix matrixB = new Matrix(new Integer(4), new Integer(3));
	private Matrix matrixAx = new Matrix(new Integer(3), new Integer(1));
	private Matrix x1 = new Matrix(new Integer(3), new Integer(1));
	private Matrix b1 = new Matrix(new Integer(4), new Integer(1));
	private Matrix x2 = new Matrix(new Integer(3), new Integer(1));
	private Matrix b2 = new Matrix(new Integer(4), new Integer(1));
	private Matrix x = new Matrix(new Integer(3), new Integer(1));
	private Matrix xmax = new Matrix(new Integer(3), new Integer(1));
	private Matrix xmaximum = new Matrix(new Integer(3), new Integer(1));
	private Integer maxNumber = 999; // default maximum
	
	
	public BackingBean() {

	}
	
	/**
	 * Method returns to user xls file with actual values at bean.
	 * */
	public void equationResultXLS(ActionEvent e){
		IEquation equation;
		EquationResult result = new EquationResult();
		try {
			equation = new EquationImpl(matrixA, matrixB, maxNumber.longValue());
			xmaximum = equation.maxX();
			result.setA(matrixA);
			result.setB(matrixB);
			result.setX(xmaximum);
			result.setInfinity(Long.parseLong(maxNumber.toString()));
			
			try {
				String path = getRealPath("/xls/");
				IXLSFileData file = locator.getXlsService().getMatrices4x3Xls(result, path);
				
				HttpServletResponse response = (HttpServletResponse) getExternalContext().getResponse();
				response.setContentType(file.getContentType());
				response.setContentLength(file.getSize());
		        response.setHeader("Cache-Control", "max-age=600");
		        response.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
		        ServletOutputStream outStream = response.getOutputStream();
				outStream.write(file.getFileData());
				outStream.flush();
			} catch (JXLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			getFacesContext().responseComplete();
		} catch (EquationException e1) {
			e1.printStackTrace();
		} 	
	}    
 
	/**
	 * Method that is backed to a submit button of a form in multiAB.xhtml.
	 * Method find maximum x.
	 */
	public void findXMaximum(ActionEvent e) {
		IEquation equation;
		try {
			equation = new EquationImpl(matrixA, matrixB, maxNumber.longValue());
			xmaximum = equation.maxX();
	    	x1 = new Matrix(xmaximum);
	    	x2 = new Matrix(xmaximum);
	    	
	    	multiAwithX1();
	    	multiBwithX2();
		} catch (EquationException e1) {
			e1.printStackTrace();
		} 
	}
	
	public void clearBX(ActionEvent e) {
		matrixB.clear();
		b2.clear();
		x2.clear();
	}

	public void multiAX(ActionEvent e) {
		multiAwithX1();
	}

	public void multiBX(ActionEvent e) {
		multiBwithX2();
	}
	
	public void multiAwithX1() {
		Matrix prvniMatice = new Matrix(matrixA);
		Matrix druhaMatice = new Matrix(x1);

		b1 = MatrixDao.multi(prvniMatice, druhaMatice);
	}

	private void multiBwithX2() {
		Matrix prvniMatice = new Matrix(matrixB);
		Matrix druhaMatice = new Matrix(x2);

		b2 = MatrixDao.multi(prvniMatice, druhaMatice);
	}
	
	public void clearAX(ActionEvent e) {
		matrixA.clear();
		b1.clear();
		x1.clear();
	}

	public void randomAB(ActionEvent e) {
		matrixA.randomNumberGenerator(maxNumber);
		matrixB.randomNumberGenerator(maxNumber);
	}

	public void randomABmaxX(ActionEvent e) {
		matrixA.randomNumberGenerator(maxNumber);
		matrixB.randomNumberGenerator(maxNumber);
		cz.uhk.max.matrix.IEquation equation;
		try {
			equation = new EquationImpl(matrixA, matrixB, maxNumber.longValue());
			xmaximum = equation.maxX();
		} catch (EquationException e1) {
			e1.printStackTrace();
		} 
	}
	
	public void randomAx(ActionEvent e) {
		matrixA.randomNumberGenerator(maxNumber);
		x1.randomNumberGenerator(maxNumber);
	}
	
	public Matrix getMatrixA() {
		return matrixA;
	}

	public void setMatrixA(Matrix a) {
		matrixA = a;
	}

	public Matrix getMatrixB() {
		return matrixB;
	}

	public void setMatrixB(Matrix b) {
		matrixB = b;
	}

	public Matrix getX1() {
		return x1;
	}

	public void setX1(Matrix x1) {
		this.x1 = x1;
	}

	public void setMaxNumber(Integer maxNumber) {
		this.maxNumber = maxNumber;
	}

	public Integer getMaxNumber() {
		return maxNumber;
	}

	public void setB1(Matrix b1) {
		this.b1 = b1;
	}

	public Matrix getB1() {
		return b1;
	}

	public void setMatrixAx(Matrix matrixAx) {
		this.matrixAx = matrixAx;
	}

	public Matrix getMatrixAx() {
		return matrixAx;
	}

	public Matrix getX2() {
		return x2;
	}

	public void setX2(Matrix x2) {
		this.x2 = x2;
	}

	public Matrix getB2() {
		return b2;
	}

	public void setB2(Matrix b2) {
		this.b2 = b2;
	}

	public void setX(Matrix x) {
		this.x = x;
	}

	public Matrix getX() {
		return x;
	}

	public void setXmax(Matrix xmax) {
		this.xmax = xmax;
	}

	public Matrix getXmax() {
		return xmax;
	}

	public void setXmaximum(Matrix xmaximum) {
		this.xmaximum = xmaximum;
	}

	public Matrix getXmaximum() {
		return xmaximum;
	}

}